package org.wang.generalcode.modules.sys.controller;

import cn.hutool.core.util.StrUtil;
import com.github.xiaoymin.knife4j.annotations.ApiOperationSupport;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.AllArgsConstructor;
import org.apache.commons.lang3.StringUtils;
import org.springframework.data.redis.connection.RedisServerCommands;
import org.springframework.data.redis.core.RedisCallback;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.wang.generalcode.modules.sys.pojo.entity.SysCache;
import org.wang.generalcode.modules.sys.pojo.model.Server;
import org.wang.generalcode.support.result.Result;

import java.util.*;

@RestController
@AllArgsConstructor
@RequestMapping("/monitor")
@Schema(description = "系统监控", name = "系统监控接口")
public class MonitorController {

    private final RedisTemplate<String, Object> redisTemplate;

    /**
     * 服务监控
     */
    @GetMapping("/server")
    @ApiOperationSupport(order = 1)
    @Schema(description = "服务监控", example = "传入menu")
    public Result server() throws Exception {
        Server server = new Server();
        server.copyTo();
        return Result.success(server);
    }

    /**
     * 缓存的图形展示
     */
    @GetMapping("/getCache")
    @ApiOperationSupport(order = 1)
    @Schema(description = "缓存的图形展示", example = "传入menu")
    public Result getCache() {
        Map<String, Object> result = new HashMap<>();
        // Step 1: 获取Redis详情
        Properties info = (Properties) redisTemplate.execute((RedisCallback<Object>) RedisServerCommands::info);
        result.put("info", info);
        // Step 2: 获取Key的数量
        Object dbSize = redisTemplate.execute((RedisCallback<Object>) RedisServerCommands::dbSize);
        result.put("keyCount", dbSize);
        // Step 3: 获取请求次数
        List<Map<String, Object>> pieList = new ArrayList<>();
        Properties commandStats = (Properties) redisTemplate.execute((RedisCallback<Object>) connection -> connection.info("commandStats"));
        if (commandStats != null && commandStats.size() != 0) {
            commandStats.stringPropertyNames().forEach(key -> {
                Map<String, Object> data = new HashMap<>();
                String property = commandStats.getProperty(key);
                data.put("name", StringUtils.substring(key, 8));
                data.put("value", StringUtils.substringBetween(property, "calls=", ",use"));
                pieList.add(data);
            });
        }
        result.put("commandStats", pieList);
        return Result.success(result);
    }


    /**
     * 获取缓存名称
     */
    @GetMapping("/getCacheNames")
    @ApiOperationSupport(order = 2)
    @Schema(description = "获取缓存名称", example = "传入menu")
    public Result<Set<SysCache>> cache() {
        Set<SysCache> allCacheList = new HashSet<>();
        Set<String> allCache = redisTemplate.keys("*");
        allCache.forEach(key -> {
            String[] parts = key.split("::", 2);
            String prefix = parts.length > 1 ? parts[0] : "";
            if (!StrUtil.isEmptyIfStr(prefix)) {
                allCacheList.add(new SysCache(prefix, ""));
            }
        });
        return Result.success(allCacheList);
    }

    /**
     * 获取缓存对象
     */
    @GetMapping("/getKeys")
    @ApiOperationSupport(order = 3)
    @Schema(description = "获取缓存对象", example = "传入menu")
    public Result getKeys(@Parameter(name = "缓存名称", required = true) @RequestParam String cacheName) {
        // 使用 Map 存储每个前缀对应的 SysCache 列表
        Map<String, List<String>> cacheMap = new HashMap<>();
        Set<String> allCache = redisTemplate.keys("*");
        allCache.forEach(key -> {
            String[] parts = key.split("::", 2);
            if (parts.length > 1) {
                String prefix = parts[0];
                String suffix = parts[1];
                cacheMap.computeIfAbsent(prefix, k -> new ArrayList<>()).add(suffix);
            }
        });
        List<String> list = cacheMap.get(cacheName);
        Set<Object> cacheKeys = new HashSet<>();
        list.forEach(key -> cacheKeys.add(key));
        return Result.success(cacheKeys);
    }


    /**
     * 获取缓存对象详细
     */
    @GetMapping("/getValue")
    @ApiOperationSupport(order = 3)
    @Schema(description = "获取缓存对象详细", example = "传入menu")
    public Result getValue(@Parameter(name = "缓存名称", required = true) @RequestParam String cacheName,
                           @Parameter(name = "key值", required = true) @RequestParam String key) {
        Object o = redisTemplate.opsForValue().get(cacheName +"::"+ key);//EhcacheUtil.get(cacheName, key);
        return Result.success(o);
    }
}
